home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-01-05 | 7.9 KB | 196 lines | [TEXT/ttxt] |
- /*
- In Java, groups of classes are bundled with the package unit. Whenever another program
- needs to access the public interface to a package, they declare their use with the import
- statement. In this applet, we are using the Abstract Window Toolkit (awt) and Applet
- classes in the Java Class Hierarchy. The “*” indicates we need subsequent subclasses as
- well.
- */
- import java.awt.*;
- import java.applet.*;
-
- /*
- Each compilation unit in Java has exactly one public interface. In the case where you do
- not define a package explicitly, your classes go into an unnamed “default” package. Also
- a restriction of the beta Java Development Kit, requires name of the source file containing
- a public interface to match the name of the public class. In this case, the file that contains
- this source is called MacTech.java. Below the MacTech class is subclassing the standard
- Applet class and overriding the required Init() method. By subclassing you gain much
- drawing and event-handling automatically and allowing you to focus on your solution.
- */
-
- public class MacTech extends java.applet.Applet {
-
- /*
- The init function is called when a Browser instantiates your instance of the Applet class.
- Any pre-flighting, memory allocation, etc can be performed to determine if the applet has
- all the resources it needs to continue.
- */
- public void init() {
- resize(300, 300); // drawing area
-
- /* The following line may look strange at first to a C/C++ programmer. But since Java
- does not have a way for the programmer to delete dynamically allocated memory, it is
- OK to not save the result of the new() operator. Whenever the applet is done using the
- Border Layout object, the garbage collector will recover the memory it allocated.
- */
- setLayout(new BorderLayout());
-
- TargetPanel theTarget = new TargetPanel();
-
- /* The base drawing context in most C++ application frameworks is the Pane class, the
- equivalent Java class is Panel. A view hierarachy is created by positioning and creating
- superviews and their sub-Panels. In the Java AWT various layout objects enforce
- positioning and function as superviews to user inteface elements. The default border
- layout object carves the display area into equal areas denoted by directional labels
- “North, South, East, West and Center” Other layout modes let you have tiled rows,
- columns and grid patterns. The Sun Java example code program “Cards” provides a
- visual map of how each layout pattern is defined.
- */
- add("Center", theTarget); // creates drawing area
-
- add("South",new PopUpMenu(theTarget)); // creates pop-up menu
-
- /*
- The Applet class implements a Panel interface. In this case we have defined the
- positioning of our drawing area (theTarget) to be at the center and a Popup Menu Panel
- directly below it.
- */
- }
- }
-
- /*
- The following classes implement the functionality of the Panels instantiated by the main
- Applet class. The TargetPanel’s job is to reflect the current status and updates controlled
- by PopUpMenuPanel class. Notice how Panels can be event-driven much like OpenDoc
- parts
- */
-
- class TargetPanel extends Panel {
- /*
- The “private protected” access specifier may appear odd or in conflict to C++
- programmers. In Java, classes in a package have a default access that is very similar to
- the “friend” specifier in C++. Even the protected access specifier does not prevent other
- classes in a packge from accessing class members. To appease C++ programmers
- alarmed by this freedom, Sun created the private protected access specifier that behaves
- indentically to the C++ protected access specifier. Public and private access specifiers
- behave identically to their C++ counterparts.
- */
- private protected int curColorIndex;
- private protected Color menuColors[] = { Color.red, Color.green, Color.blue, Color.yellow,
- Color.cyan, Color.magenta, Color.black };
-
- TargetPanel() {
- setBackground(Color.white);
- }
-
- public void SetColorIndex(int inColorIndex) {
- curColorIndex = inColorIndex;
- }
-
- /* The Graphics class contains all the QuickDraw-like routines for drawing arcs, ovals,
- rectangles and round rectangles. The paint method of a Panel is called in response to
- update events only, so take this into consideration when threads or other updating
- changes state information that an update routine depends on.
- */
- public void paint(Graphics g){
- g.setColor(menuColors[curColorIndex]);
- g.setPaintMode();
-
- g.fillRect(10,10, 100, 100);
- }
-
- /* Panels are equipped to handle all user-input events like keyboard input, mouse
- movement, clicks, and dragging. Most event processing can be left to the built-in classes.
- In this case, I’m trapping the event sent to a Panel when the browser is closing the
- window. I could prompt the user for input or alter the handling of the event.
- */
- public boolean handleEvent(Event inEvent) {
- switch (inEvent.id) {
- case Event.WINDOW_DESTROY:
- System.exit(0);
- return true;
-
- default:
- return false;
- }
- }
- }
-
- /*
- Rather than implement an entire menu bar for a menu, I decided to opt for the popup
- menu. In Java, the popup menu interface element is called Choice selection. In order to
- respond to the user, I let the Panel perform the normal event processing regarding the
- tracking and updating. By overriding the action method, I am able to respond only to
- changes in the value of the PopUp menu and send an update signal to the target Panel.
- */
-
- class PopUpMenu extends Panel {
- TargetPanel thisPanel;
-
- /* The constructor for our class receives a reference to Panel that will need updates when
- the value of the PopUp Menu is changed. Since as of this writing, Java lacks a formal
- resource format, thus all user interface elements must be hard-coded. Bummer. It’s
- likely IDE vendors on multiple platforms or perhaps Sun may define a resource format to
- allow strings, menus and control titles to be defined in an external manner.
- */
- public PopUpMenu(TargetPanel inMenu) {
- thisPanel = inMenu;
-
- setLayout(new FlowLayout());
- setBackground(Color.lightGray);
-
- Choice colorMenu = new Choice();
-
- colorMenu.addItem("Red");
- colorMenu.addItem("Green");
- colorMenu.addItem("Blue");
- colorMenu.addItem("Yellow");
- colorMenu.addItem("Cyan");
- colorMenu.addItem("Magenta");
- colorMenu.addItem("Black");
-
- colorMenu.setBackground(Color.lightGray);
- add(colorMenu);
- }
-
- public void paint(Graphics g) {
- Rectangle r = bounds();
-
- g.setColor(Color.lightGray);
-
- /* This is one my favorite Graphics toolkit calls. It paints those 3D-like shadows around
- a standard rectangle to yield a bevel. Maybe an Apple engineer can add one to Copland.
- */
- g.draw3DRect(0, 0, r.width, r.height, false);
- }
-
- /* Generally in a layout you may have several user interface elements of various object types. To
- identify the correct object type you may use Runtime Type Indentication (RTTI) before attempting to
- typecast and access a particular method. The instanceof operator in Java returns true of an object
- is a proper instance of Class.
- */
- public boolean action(Event inEvent, Object inObject) {
- if (inEvent.target instanceof Choice) { // Correct object type - PopUpMenu
- String menuSelection = (String) inObject;
-
- /* Since we are responding to changes in the PopUpMenu control, the action method
- gives us the current value. The value of a Choice object is a String. This is a little
- inconvenient since we can not use Strings in a switch statement. Also it duplicates the
- references to the contents of the menu making program maintainence difficult. I illustrate
- how to process the normal value returned and a way around relying on the String itself.
- */
- if (menuSelection.equals("Red")) // processing standard value returned
- thisPanel.SetColorIndex(0);
- else // because of RTTI I can typecast the target object and
- // access the menu index directly
- thisPanel.SetColorIndex(((Choice) inEvent.target).getSelectedIndex());
-
- /*
- Sends the update signal to the Drawing Panel so the change can be updated immediately
- */
- thisPanel.repaint();
- }
- return true;
- }
- }
-